#!/usr/bin/env bash
#
# netflix pro seu terminal... ou quase isso
#
# Para detalhes sobre a licença veja o arquivo COPYING

# Adiciona caracteres em um linha
# Argumentos:
#   max
#   start
#   char
# Retorno:
#   Nenhum
fill_line() {
  declare -i start max
  local char

  max=${1}
  start=${2:-0}
  char="${3:- }"

  printf "%.s${char}" $(seq ${start} ${max})
}

# Desenha corpo (background + borda) do layout de acordo com o número de linhas
# Globais:
#   GEO[BD_W]
#   GEO[HD_P]
#   C[BORDER]
# Argumentos:
#   start
#   lines
#   color
# Retorno:
#   Nenhum
draw() {
  local spc bord bdy border hdrw
  declare -i start lines color

  start=${1}
  lines=${2}
  color=${3}

  (( lines+=start ))
  hdrw=$(( GEO[BD_W]-GEO[HD_P] ))
  spc="$(fill_line ${hdrw} 1)"
  bord="$(fill_line ${hdrw} 1 ▀)"

  bdy="${C[BORDER]} \e[48;5;${color}m${spc}${C[BORDER]} \n"
  border="${C[BORDER]} \e[38;5;${color}m${bord}${C[BORDER]} \e[48;5;${color}m"

  cup 0 ${start}
  tput ed

  for (( i=start; i <lines; i++ )); do
      printf "${bdy}"
  done

  printf "${border}"
}

# Posiciona cursor na tela. Wrapper para 'tput cup' para passar X e Y com offset
# Argumentos:
#   x
#   y
# Returno:
#   Nenhum
cup() {
  local x y
  x="${1}"
  y="${2}"

  tput cup ${y} ${x}
}

# Retorna o valor necessário para alinhar um elemento horizontalmente no centro
# de 80 colunas.
# Globais:
#   GEO[BD_W]
# Argumentos:
#   width
# Retorno:
#   valor para o alinhamento lateral
center() {
  declare -i width
  width="${1}"

  printf "%d" $(((GEO[BD_W]/2) - (width/2)))
}

# Imprime o header
# Argumentos:
#   Nenhum
# Retorno:
#   Nenhum
header() {
  declare -a logo
  declare -i x y

  tput civis

  logo[0]="${C[BORDER]} ${C[RED]}▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄${C[BORDER]} ${E[RST]}"
  logo[1]="${C[BORDER]} ${C[BG_RED]}${C[WHT]}                                                                              ${C[BORDER]} ${E[RST]}"
  logo[2]="${C[BORDER]} ${C[BG_RED]}${C[WHT]}   ▄    ▄            ▄     ▄▄▄▄▄▄           ▄                    ▄            ${C[BORDER]} ${E[RST]}"
  logo[3]="${C[BORDER]} ${C[BG_RED]}${C[WHT]}   █${C[BLK]}█${C[WHT]}   █${C[BLK]}█${C[WHT]}           █${C[BLK]}█${C[WHT]}    █${C[BLK]}█${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}          ▀${C[BLK]}█${C[WHT]}                   ▀${C[BLK]}█${C[WHT]}           ${C[BORDER]} ${E[RST]}"
  logo[4]="${C[BORDER]} ${C[BG_RED]}${C[WHT]}   █${C[BG_BLK]}▀${C[BG_RED]}▄  █${C[BLK]}█${C[WHT]} ▄▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}▄  ▀${C[BG_BLK]}▀${C[BG_RED]}█${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BLK]}▄${C[WHT]}  █${C[BG_BLK]}▄${C[BG_RED]}▄▄    █▄▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BLK]}▄${C[WHT]} ▀█${C[BLK]}▄${C[WHT]}  ▄▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}█${C[BLK]}▄${C[WHT]} █${C[BLK]}▄${C[WHT]}   █${C[BLK]}▄${C[WHT]} ▀█${C[BLK]}▄${C[WHT]}  ▄▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BLK]}▄${C[WHT]}  ${C[BORDER]} ${E[RST]}"
  logo[5]="${C[BORDER]} ${C[BG_RED]}${C[WHT]}   █${C[BLK]}█${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BG_BLK]}▀${C[BG_RED]}▄█${C[BLK]}█${C[WHT]} █${C[BG_BLK]}▄${C[BG_RED]}▄▄▄█${C[BLK]}█${C[WHT]}   █${C[BLK]}█${C[WHT]}    █${C[BLK]}█${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}   █${C[BLK]}█${C[WHT]}${C[BLK]}▀${C[WHT]}      █${C[BLK]}█${C[WHT]}  █${C[BLK]}█${C[WHT]}   █${C[BLK]}█${C[WHT]} █${C[BLK]}█${C[WHT]}   █${C[BLK]}█${C[WHT]}  █${C[BLK]}█${C[WHT]}  ▀${C[BG_BLK]}▄${C[BG_RED]}▄▄▄    ${C[BORDER]} ${E[RST]}"
  logo[6]="${C[BORDER]} ${C[BG_RED]}${C[WHT]}   █${C[BLK]}█${C[WHT]}  ${C[BLK]}▀${C[WHT]}█${C[BLK]}█${C[WHT]} █${C[BLK]}█${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}   █${C[BLK]}█${C[WHT]}    █${C[BLK]}█${C[WHT]}      █${C[BLK]}█${C[WHT]}       █${C[BLK]}█${C[WHT]}  █${C[BLK]}█${C[WHT]}   █${C[BLK]}█${C[WHT]} █${C[BLK]}█${C[WHT]}   █${C[BLK]}█${C[WHT]}  █${C[BLK]}█${C[WHT]}    ${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}${C[BLK]}▀${C[WHT]}█${C[BLK]}▄${C[WHT]}  ${C[BORDER]} ${E[RST]}"
  logo[7]="${C[BORDER]} ${C[BG_RED]}${C[WHT]}   ▀${C[BLK]}█${C[WHT]}   ▀${C[BLK]}█${C[WHT]}  ▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BLK]}▄${C[WHT]}     ▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BLK]}▄${C[WHT]} ▀${C[BLK]}█${C[WHT]}      ▀${C[BLK]}█${C[WHT]}      ▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BLK]}▄${C[WHT]}  ▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}█${C[BLK]}█${C[WHT]}  ▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BLK]}█${C[WHT]} ▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BLK]}▄${C[WHT]} ▀${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BG_BLK]}▀${C[BG_RED]}${C[BLK]}▄${C[WHT]}${C[BLK]}▀${C[WHT]}  ${C[BORDER]} ${E[RST]}"
  logo[8]="${C[BORDER]} ${C[BG_RED]}${C[WHT]}                                                     █${C[BLK]}█${C[WHT]}             v${VERSION}    ${C[BORDER]} ${E[RST]}"
  logo[9]="${C[BORDER]} ${C[BG_RED]}${C[WHT]}                                                      ${C[BLK]}▀${C[WHT]}                       ${C[BORDER]} ${E[RST]}"

  x=0

  for (( y=0; y <=9; y++ )); do
    cup ${x} ${y}
    printf "%s" "${logo[y]}";
  done

  tput cnorm
}

# Imprime erro e saí
# Argumentos:
#   err_ext
#   err_msg
#   err_cmd
# Retorno:
#   Nenhum
error() {
  local err_ext err_msg err_cmd

  err_ext="${1}"
  err_msg="${2}"
  err_cmd="${3}"

  printf "\n%s\n\n" "${err_msg}" >&2

  [[ "${err_cmd}" == usage ]] && usage >&2

  exit "${err_ext}"
}

# Retorna valor para posicionar o prompt verticalmente
# Globais:
#   HD_S
# Argumentos:
#   length
# Retorno:
#   valor para posicionar o prompt
prompt_vertical_pos() {
  local -i length

  length=${1}
  printf "%d" $(( HD_S+length+2 ))
}

# already using a tmp file. Should get properly set
# Toca o stream
# Globais:
#   BUFF_DIR
# Argumentos:
#   stream_name
#   stream_url
# Retorno:
#   Nenhum
play() {
  local stream_name stream_url

  stream_name="${1}"
  stream_url="${2}"

  tput cuu1
  tput cuf 2
  tput ech 77

  printf "Reproduzindo: %s" "${stream_name}"

  if [[ "$(tty)" =~ "tty" ]]; then
    tput civis
    mplayer -fs -vo fbdev2 -vf scale -zoom "${stream_url}" &> /dev/null
    tput cnorm
  else
    mplayer -slave -input file="${BUFF_DIR}"/mplayer "${stream_url}" &> /dev/null
  fi
}

#TODO: this is totally broken, now you can see why some work is needed
# Imprime breadcrumb
# Globais:
#   BREADCRUMB
#   GEO[BD_W]
#   GEO[HD_P]
#   C[BORDER]
#   C[BG_WHT]
#   BREADCRUMB
# Argumentos:
#   Nenhum
# Retorno:
#   Nenhum
breadcrumb() {
  declare -i i fill breadcrumb_padding
  local spc

  tput civis
  cup 1 ${GEO[HD_H]}

  if [[ -z ${BREADCRUMB[1]} ]]; then

    breadcrumb_padding=2
    fill=$(( GEO[BD_W]-GEO[HD_P]-${#BREADCRUMB[0]}-breadcrumb_padding ))
    spc="$(fill_line ${fill})"

    printf "${C[BG_WHT]}${C[RED]} %s%s${C[BORDER]}" "${BREADCRUMB[0]}" "${spc}"

  elif [[ -n ${BREADCRUMB[1]} ]]; then

    breadcrumb_padding=8
    breadcrumb_length=0

    for item in ${BREADCRUMB[@]}; do
      (( breadcrumb_length=breadcrumb_length+${#item} ))
    done

    fill=$(( GEO[BD_W]-GEO[HD_P]-breadcrumb_length-breadcrumb_padding ))
    spc="$(fill_line ${fill})"

    printf "\e[K${C[BG_WHT]}${C[RED]} %s > %s > %s${C[BORDER]} " "${BREADCRUMB[@]}" "${spc}"

  fi

  tput cnorm
}


# Printa opção do menu
# Globais:
#   Nenhum
# Argumentos
#   option
#   flag
# Retorno
#   Nenhum
selector() {
  local option flag

  option="${1}"
  flag="${2}"

  if [[ ${flag} == "normal" ]]; then
    printf "${C[SLT]}%s" "${option}"
  elif [[ ${flag} == "invert" ]]; then
    printf "\e[7m %s \e[27m" "${option}"
  fi
}

# Imprime tecla selecionada
# GLOBAIS:
#   KEY[ENTER]
#   KEY[TAB]
#   KEY[BKSP]
# Argumentos
#   REPLY
# Retorno
#   Nenhum
key_input() {
  IFS=;
  local key

  read -rsN 100 -t 0.001

  while true; do
    read -rsN 1
    key=${REPLY}

    case "${key}" in

      ${KEY[ENTER]}|l)

        printf "enter"
        break
        ;;

      ${KEY[TAB]})

        printf "tab"
        break
        ;;

      ${KEY[BKSP]}|h)

        printf "bksp"
        break
        ;;

     k)

        printf "up"
        break
        ;;

     j)

        printf "down"
        break
        ;;

    esac
    key=;
  done
}

# Gera menu
# Globais:
#   GEO[MG_L]
#   GEO[MG_T]
#   GEO[HD_H]
#   GEO[BD_H]
#   C[NRM]
#   C[SLT]
#   C[NRM]
# Argumentos:
#   options
#   color
# Retorno:
#   Nenhum
options_list() {
  declare -n options
  declare -i color start max page index limit pos_y slct lines
  local spc

  options="${1}"
  color="${2}"
  page="${3}"

  slct=1

  tput civis

  (( array_length=${#options[@]} ))
  (( max=${#array_length} ))

  tput setab ${color}
  tput setaf 50

  GEO[MG_T]=$(prompt_vertical_pos ${#options})
  cup ${GEO[MG_L]} ${GEO[MG_T]}

  tput ed
  lines=1
  (( start=GEO[HD_H]+lines ))
  draw ${start} ${GEO[BD_H]} "${color}"

  lines=2
  (( GEO[MG_T]=GEO[HD_H]+lines ))

  (( index=1+(VERT_SPACE*page) ))
  (( limit=(index+VERT_SPACE < array_length) ? (1+page)*VERT_SPACE : array_length))

  while :; do
      ((pos_y=GEO[MG_T]))

    for (( i=index; i < limit ; i++ )); do
      cup 2 ${pos_y}
      tput ech 77

      lines=1
      if (( pos_y == $((slct+GEO[HD_H]+lines)))); then
        selector "${options[i]}" "invert"
      else
        selector "${options[i]}" "normal"
      fi
      ((pos_y++))
    done

    case "$(key_input)" in
    "enter")
             break
             ;;
     "bksp")
             ((slct=0))
             break
             ;;
       "up")
             (( (--slct < 1) ? ((slct=limit-1)) : continue  ))
             ;;
     "down")
             (( (++slct >= limit) ? ((slct=1)) : continue  ))
             ;;
          *)
             ;;
    esac
  done

  tput cnorm

  return ${slct}
}

#TODO: major refactor here
# Retorna link de um vídeo
# Argumentos:
#   id
# Retorno:
#   url do vídeo
get_link() {
  local id url

  id="${1}"
  if [[ "http" =~ "${id}" ]]; then
    url="${id}"
  else
    url="https://www.blogger.com/video-play.mp4?contentId=${id}"
  fi

  printf "%s" "${url}"
}

#TODO: major refactor here
# Busca videos no banco de dados
# Globais:
#   GEO[MG_L]
#   GEO[MG_T]
#   BREADCRUMB
#   C[MN_SRCH]
#   HD_S
#   EXIT[OK]
# Argumentos:
#   search_video
# Retorno:
#   Nenhum
search() {
  local search_video search_result choice url
  declare -a list_name url
  declare -i array_length start max page page_count search_count
  declare -ri INIT=1

  search_video="${1}"
  color="${C[MN_SRCH]}"
  page=0

  list_name[0]="Retornar"
  search_result=$(grep -i "${search_video}" "${DB}")

  if [[ -z ${search_result:+x} ]]; then

    GEO[MG_T]=$(prompt_vertical_pos ${#opts})
    cup ${GEO[MG_L]} ${GEO[MG_T]}

    printf "Desculpe, nenhum resultado encontrado."
    read

    return "${EXIT[ERR]}"
  fi

  mapfile -O 1 -t list_name <<<"$(cut -d\^ -f2-3 <<<"${search_result}")"
  mapfile -O 1 -t url <<<"$(cut -d\^ -f4 <<<"${search_result}")"

  search_count=$(( --${#list_name[@]} ))
  if (( search_count > VERT_SPACE )); then
    mapfile -t pages <<<"$(seq ${page} ${VERT_SPACE} ${search_count})"
  else
    pages=( 0 )
  fi

  page_count=${#pages[@]}

  BREADCRUMB[1]="Busca: ${search_video}"

  breadcrumb

  tput setab ${C[MN_SRCH]}
  tput ed

  cup ${GEO[MG_L]} ${GEO[HD_H]}

  while :; do
    options_list list_name ${color} ${page}
    choice=$?
    printf "Página %s de %s" "$(( page+INIT ))" "${page_count}"

    if [[ ${choice} == "p" ]]; then
        (( (page < (page_count-1) ) ? page++ : continue ))
    elif [[ ${choice} == "a" ]]; then
        (( (page > 0) ? page-- : continue  ))
    fi

    [[ " ${!list_name[@]} " =~ " ${choice} " ]] || continue

    [[ ${choice} == "0" ]] && return ${EXIT[OK]}

    url=$(get_link "${url[choice]}")
    play "${list_name[choice]}" "${url}"
  done
}

#TODO: major refactor here
# Cria menu de episódios de desenhos ou séries
# Globais:
#   BREADCRUMB
#   C[MN_SRCH]
#   GEO[MG_L]
#   GEO[MG_T]
#   EXIT[OK]
# Argumentos:
#   title
#   color
# Retorno:
#   Nenhum
get_episodes() {
  local title db color episodes
  local -a list_name url pages
  declare -i page page_count episode_count
  declare -ri INIT=1

  title="${1}"
  db="${2}"
  color="${3}"
  page=0

  id=$(grep -i "${title}" data/${db}/index | cut -d\^ -f1)
  episodes=$(grep -i "^${id}\^" data/${db}/episodes)

  list_name[0]="Retornar"
  mapfile -O 1 -t list_name <<<"$(cut -d\^ -f5 <<<"${episodes}")"
  mapfile -O 1 -t url <<<"$(cut -d\^ -f2 <<<"${episodes}")"

  episode_count=$(( --${#list_name[@]} ))
  if (( episode_count > VERT_SPACE )); then
    mapfile -t pages <<<"$(seq ${page} ${VERT_SPACE} ${episode_count})"
  else
    pages=( 0 )
  fi

  page_count=${#pages[@]}

  BREADCRUMB[2]="${title}"

  breadcrumb

  tput setab ${color}
  tput ed

  cup ${GEO[MG_L]} ${GEO[HD_H]}

  while :; do
    options_list list_name ${color} ${page}
    choice=$?
    printf "Página %s de %s" "$(( page+INIT ))" "${page_count}"

    if [[ ${choice} == "p" ]]; then
        (( (page < (page_count-1) ) ? page++ : continue ))
    elif [[ ${choice} == "a" ]]; then
        (( (page > 0) ? page-- : continue  ))
    fi

    [[ " ${!list_name[@]} " =~ " ${choice} " ]] || continue

    [[ ${choice} == "0" ]] && return ${EXIT[OK]}

    url=$(get_link ${url[choice]})
    play "${list_name[choice]}" "${url}"
  done
}

# Gera menus para categorias
# Globais:
#   BREADCRUMB
#   C[MN_TOON]
#   GEO[MG_L]
#   GEO[MG_T]
#   EXIT[OK]
# Argumentos:
#   category
#   abbr
#   color
# Retorno:
#   Nenhum
menu() {
  local choice category abbr color start_at
  declare -i page page_count opts_count
  declare -ri INIT=1
  local -a opts

  category="${1}"
  db="${2}"
  color="${3}"

  page=0

  BREADCRUMB[1]="${category}"
  breadcrumb

  opts[0]="Retornar"
  mapfile -O 1 -t opts <<<"$(cut -d\^ -f2 data/${db}/index)"

  opts_count=$(( --${#opts[@]} ))
  mapfile -t pages <<<"$(seq ${page} ${VERT_SPACE} ${opts_count})"

  page_count=${#pages[@]}
  while :; do
    options_list opts ${color} ${page}
    choice=$?

    printf "Página %s de %s  " "$(( page+INIT ))" "${page_count}"

    if [[ ${choice} == "p" ]]; then
        (( (page < (page_count-1) ) ? page++ : continue ))
    elif [[ ${choice} == "a" ]]; then
        (( (page > 0 ) ? page-- : continue  ))
    fi

    [[ " ${!opts[@]} " =~ " ${choice} " ]] || continue

    [[ ${choice} == "0" ]] && return ${EXIT[OK]}

    #TODO here you need to call some function to bring metadata and urls OR
    # serie/toon metada and episode_list depend on what menu you're in
    get_episodes "${opts[choice]}" ${db} ${color}
  done
}

# Imprime o número de linhas e colunas do terminal
# Globais:
#   GEO[WD_W]
#   GEO[WD_H]
#   GEO[MG_B]
#   GEO[HD_H]
#   GEO[BD_B]
#   HD_S
#   VERT_SPACE
# Argumentos:
#   Nenhum
# Retorno:
#   Nenhum
get_window_size() {
  GEO[WD_W]=$(tput cols)
  GEO[WD_H]=$(tput lines)

  (( HD_S=GEO[HD_H]+GEO[MG_B] ))

  (( GEO[BD_H]=GEO[WD_H]-HD_S ))

  (( VERT_SPACE=GEO[BD_H]-GEO[MG_B]-GEO[BD_B]-4 ))
}

main() {
  readonly VERSION="0.1.0"
  readonly -A EXIT=( [OK]=0 [ERR]=1 )

  local dependencies

  dependencies=("mplayer")

  for dependency in "${dependencies[@]}"; do
    type "${dependency}" &>/dev/null ||
        error ${EXIT_[ERR]} "${dependency} não foi encontrado."
  done

  declare -rA C=(
    [RED]=$'\e[38;5;160m' [BORDER]=$'\e[48;5;232m'
    [WHT]=$'\e[38;5;231m' [BG_RED]=$'\e[48;5;160m'
    [BLK]=$'\e[38;5;16m'  [BG_WHT]=$'\e[48;5;231m'
    [NRM]=$'\e[38;5;177m' [BG_BLK]=$'\e[48;5;16m'
    [SLT]=$'\e[38;5;50m'  [BG_GRY]=$'\e[48;5;240m'
    [MN_MAIN]=240 [MN_SRCH]=238 [MN_TOON]=242
    [MN_SERS]=235
  )

  declare -rA E=(
    [RST]=$'\e[m' [CPL]=$'\e[F'
    [CNL]=$'\e[E' [CHA]=$'\e[G'
  )

  declare -rA KEY=(
    [TAB]=$'\t'    [UP]=$'\e[A'
    [ESC]=$'\e'    [DOWN]=$'\e[B'
    [BKSP]=$'\b'
    [ENTER]=$'\n'
  )

  local opts choice search_video
  local TMPDIR BUFF_NAME MKTEMP BUFF_DIR
  declare -a BREADCRUMB
  declare -i i line_space HD_S VERT_SPACE

  declare -A GEO=(
    [WN_W]=0  [WN_H]=0
    [HD_H]=10 [HD_P]=2
    [BD_W]=80 [BD_H]=0  [BD_B]=2
    [MG_T]=0  [MG_B]=2  [MG_L]=2
  )

  if [[ -d "/dev/shm" ]]; then
    TMPDIR="/dev/shm"
  else
    TMPDIR="/tmp"
  fi

  BUFF_NAME="netfriquis"
  MKTEMP=$(which mktemp)

  if [[ -x ${MKTEMP} ]]; then
    BUFF_DIR=$(mktemp --tmpdir=${TMPDIR} -d -t ${BUFF_NAME}.XXXXXXXXXX)
  else
    BUFF_DIR="${TMPDIR}/${BUFF_NAME}.${RANDOM}"
    mkdir -p ${BUFF_DIR}
  fi
  BUFFER="${BUFF_DIR}/${BUFF_NAME}"

  trap 'rm "${BUFF_DIR}"/*; rmdir "${BUFF_DIR}"' EXIT
  trap 'get_window_size' WINCH

  get_window_size

  opts=("Sair" "Ajuda" "Desenhos" "Filmes" "Radios")

  tput smcup
  clear

  header

  while :; do

    BREADCRUMB[0]="Principal"
    breadcrumb
    options_list opts ${C[MN_MAIN]}
    choice=$?

    tput sc

    [[ " ${!opts[@]} " =~ " ${choice} " ]] || continue

    case "${choice}" in
      0) clear; tput rmcup; tput cnorm; exit "${EXIT[OK]}" ;;
      1) ;;
      2)
        menu ${opts[choice]} 'toons'
        ;;
      3)
        menu ${opts[choice]} 'movies'
        ;;
      4)
        menu ${opts[choice]} 'radios'
        ;;
      5)
        tput rc
        printf "Digite o nome do vídeo: "
        line_space=$(( GEO[BD_W]-30 ))
        tput ech ${line_space}

        read search_video

        [[ -n "${search_video}" ]] && search "${search_video}" || continue
        ;;
    esac
  done
}

main "$@"
